package v1

import (
	"fmt"
	"github.com/astaxie/beego/validation"
	"github.com/gin-gonic/gin"
	"github.com/unknwon/com"
	"net/http"
	"repairs/pkg/app"
	"repairs/pkg/e"
	"repairs/pkg/setting"
	"repairs/pkg/util"
	"repairs/service/malfunction_service"
)

func MalFunctions(c *gin.Context) {
	method := c.Query("_method")
	if method == "get" {
		GetMalfunctions(c)
	} else if method == "add" {
		AddMalfunction(c)
	}
}

// 获取malfunction校验
type GetMalfunctionJSON struct {
	Room    string `json:"room"`
	Type    int    `json:"type" valid:"Range(0,4)"`
	State   int    `json:"state" valid:"Range(0,4)"`
	PageNum int    `json:"page_num" valid:"Required"`
}

// @Summary 获取报修列表
// @Accept json
// @Tags 报修
// @Produce json
// @Param room body string false "故障所在教室/机房"
// @Param type body int false "故障类型"
// @Param state body int false "故障状态"
// @Param page_num body int true "页号"
// @Success 200 {object} app.Response
// @Failure 500 {object} app.Response
// @Router /api/v1/malfunctions [get]
func GetMalfunctions(c *gin.Context) {
	var (
		appG              = app.Gin{C: c}
		data              map[string]interface{}
		json                 GetMalfunctionJSON
	)

	httpCode, errCode := app.BindAndValid(c, &json)
	for true {
		if errCode != e.SUCCESS {
			break
		}

		malfunctionService := malfunction_service.Malfunction{
			PageNum:  util.GetPageByNum(json.PageNum),
			PageSize: setting.AppSetting.PageSize,
			Room:     json.Room,
			State:    json.State,
			Type:     json.Type,
		}

		total, err := malfunctionService.Count()
		if err != nil {
			httpCode, errCode = http.StatusInternalServerError, e.ErrorCountMalfunctionFail
			break
		}

		malfunctions, err := malfunctionService.GetAll()
		if err != nil {
			httpCode, errCode = http.StatusInternalServerError, e.ErrorGetMalfunctionFail
			break
		}
		data = make(map[string]interface{})
		data["lists"] = malfunctions
		data["total"] = total
		break
	}

	appG.Response(httpCode, errCode, data)
}

// 增加malfunction校验
type AddMalfunctionJSON struct {
	UserID      int    `json:"user_id" valid:"Required;Min(1)"`
	Room        string `json:"room" valid:"Required"`
	Position    string `json:"position" valid:"Required"`
	Type        int    `json:"type" valid:"Required;Range(1,4)"`
	Description string `json:"description" valid:"Required"`
}

// @Summary 添加报修
// @Accept json
// @Tags 报修
// @Produce json
// @Param user_id body int true "提出报修的用户id"
// @Param room body string true "故障所在教室/机房"
// @Param position body string true "故障所在机房的具体位置"
// @Param type body int true "故障类型"
// @Param description body string true "故障描述"
// @Success 200 {object} app.Response
// @Failure 500 {object} app.Response
// @Router /api/v1/malfunctions [post]
func AddMalfunction(c *gin.Context) {
	var (
		appG = app.Gin{C: c}
		json AddMalfunctionJSON
	)

	httpCode, errCode := app.BindAndValid(c, &json)
	for true {
		if errCode != e.SUCCESS {
			break
		}

		malfunctionService := malfunction_service.Malfunction{
			UserID:      json.UserID,
			Room:        json.Room,
			Position:    json.Position,
			Type:        json.Type,
			Description: json.Description,
		}

		if err := malfunctionService.Add(); err != nil {
			httpCode, errCode = http.StatusInternalServerError, e.ErrorAddMalfunctionFail
			break
		}
		break
	}

	appG.Response(httpCode, errCode, nil)
}

// 编辑malfunction校验
type EditMalfunctionJSON struct {
	ID    int `json:"id" valid:"Required;Min(1)"`
	State int `json:"state" valid:"Required;Range(1,4)"`
}

// @Summary 更新报修
// @Accept json
// @Tags 报修
// @Produce json
// @Param id body int true "报修id"
// @Param state body int true "报修新的状态"
// @Success 200 {object} app.Response
// @Failure 500 {object} app.Response
// @Router /api/v1/malfunctions/{id} [put]
func EditAMalfunction(c *gin.Context) {
	var (
		appG = app.Gin{C: c}
		json EditMalfunctionJSON
	)

	httpCode, errCode := app.BindAndValid(c, &json)
	// error handle
	for true {
		fmt.Printf("%#v\n", json)
		if errCode != e.SUCCESS {
			break
		}

		malfunctionService := malfunction_service.Malfunction{
			ID:    json.ID,
			State: json.State,
		}
		// 检查id是否存在
		exists, err := malfunctionService.ExistByID()
		if err != nil {
			print(err)
			httpCode, errCode = http.StatusInternalServerError, e.ERROR
			break
		} else if !exists {
			httpCode, errCode = http.StatusOK, e.ErrorNotExistMalfunctionFail
			break
		}
		// 更新
		err = malfunctionService.UpdateState()
		if err != nil {
			httpCode, errCode = http.StatusInternalServerError, e.ErrorEditMalfunctionFail
			break
		}
		break
	}
	appG.Response(httpCode, errCode, nil)
}

// @Summary 删除报修
// @Produce json
// @Tags 报修
// @Param id path int true "报修id"
// @Success 200 {object} app.Response
// @Failure 500 {object} app.Response
// @Router /api/v1/malfunctions/{id} [delete]
func DeleteMalfunction(c *gin.Context) {
	var (
		appG              = app.Gin{C: c}
		valid             = validation.Validation{}
		id                = com.StrTo(c.Param("id")).MustInt()
		httpCode, errCode = http.StatusOK, e.SUCCESS
	)
	valid.Min(id, 1, "id").Message("ID必须大于0")
	// error handle
	for true {
		if valid.HasErrors() {
			app.MarkErrors(valid.Errors)
			httpCode, errCode = http.StatusOK, e.InvalidParams
			break
		}

		malfunctionService := malfunction_service.Malfunction{ID: id}
		exists, err := malfunctionService.ExistByID()
		if err != nil {
			httpCode, errCode = http.StatusInternalServerError, e.ERROR
			break
		}

		if !exists {
			httpCode, errCode = http.StatusOK, e.ErrorNotExistMalfunctionFail
			break
		}
		err = malfunctionService.Delete()

		if err != nil {
			httpCode, errCode = http.StatusInternalServerError, e.ErrorDeleteMalfunctionFail
			break
		}
		break
	}
	appG.Response(httpCode, errCode, nil)
}
